﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Security.Permissions;
using System.Web;
using System.Web.Hosting;
using System.Web.Security;
using System.Xml;

namespace oAuthDemo.OpenIDProvider
{
    public class ReadOnlyXmlMembershipProvider
    {
        class UserModel
        {
            public string UserName { get; set; }
            public string Email { get; set; }
            public string Password { get; set; }
        }

        public ReadOnlyXmlMembershipProvider()
        { 
        }

        public ReadOnlyXmlMembershipProvider(string xmlFileName)
        {
            this.XmlFileName = xmlFileName;
        }

        private Dictionary<string, UserModel> users;
        public string XmlFileName { get; set; }
          
        public bool ValidateUser(string username, string password)
        {
            // Validate input parameters
            if (string.IsNullOrEmpty(username) ||
                string.IsNullOrEmpty(password))
            {
                return false;
            }

            try
            {
                // Make sure the data source has been loaded
                this.ReadMembershipDataStore();

                // Validate the user name and password
                UserModel user;
                if (this.users.TryGetValue(username, out user))
                {
                    if (user.Password == password)
                    { // Case-sensitive
                        // NOTE: A read/write membership provider
                        // would update the user's LastLoginDate here.
                        // A fully featured provider would also fire
                        // an AuditMembershipAuthenticationSuccess
                        // Web event
                        return true;
                    }
                }

                // NOTE: A fully featured membership provider would
                // fire an AuditMembershipAuthenticationFailure
                // Web event here
                return false;
            }
            catch (Exception e)
            {
                return false;
            }
        }
          

        internal string GetSalt(string userName)
        {
            // This is just a sample with no database... a real web app MUST return 
            // a reasonable salt here and have that salt be persistent for each user.
            this.ReadMembershipDataStore();
            return this.users[userName].Email;
        }

        // Helper method
        private void ReadMembershipDataStore()
        {
            lock (this)
            {
                if (this.users == null)
                {
                    this.users = new Dictionary<string, UserModel>(16, StringComparer.InvariantCultureIgnoreCase);
                    XmlDocument doc = new XmlDocument();
                    doc.Load(XmlFileName);
                    XmlNodeList nodes = doc.GetElementsByTagName("User");

                    foreach (XmlNode node in nodes)
                    {
                        // Yes, we're misusing some of these fields.  A real app would
                        // have the right fields from a database to use.
                        var user = new UserModel()
                        {                       // Provider name
                            UserName = node["UserName"].InnerText, // Username
                            Email = node["Salt"].InnerText,     // Email
                            Password = node["Password"].InnerText,
                        };  // lastLockoutDate

                        this.users.Add(user.UserName, user);
                    }
                }
            }
        }
    }
}